/*
1.判断质数
2.随机验证码
3.颜色随机数
4.随机数
5.绑定事件
6.解绑事件
7.随机整数
*/

// 判断 质数 函数 
// num 是 外界输入的,需要判断的数值
// 如果是 质数 返回值是 true 如果不是 质数 返回值是 false
function isPrime(num){
    // 因为 需要的 返回值是 true 或者 false
    // 变量bool 中 默认 存储 true
    var bool = true;
    for(var i = 2 ; i <= num /2 ; i++){
        if( num % i === 0 ){
            // 如果 发生整除 bool 赋值 false break 终止循环
            bool = false;
            break;
        }
    }     
    // 判断结果存储在 bool 中 
    // 通过 return 来定义函数的返回值是 bool 中存储的数据
    return bool;       
}









/*  
    随机验证码函数
    
    @param number number   验证码字符串位数
    @param str    string   验证码字符串内容  
    @param bool   boolean  验证码字符串是否允许有重复的字符出现

    @return vc    string   返回值是生成的验证码字符串 

    说明: 随机设定 指定位数 指定内容 是否允许重复字符出现的 验证码字符串
          
          验证码最少4位,默认值是6位
    
          验证码字符串内容 默认是 数字,大小写字母

          默认验证码允许出现重复字符
*/
function getVc(number = 6 , str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' , bool = true){
    // 1,验证码位数参数判断
    if( number < 4 ){
        return '验证码位数不能小于4位';
    }

    // 2, 定义一个变量储存随机生成的验证码字符串
    var vc = '';

    // 3, 循环遍历,判断生成验证码字符串
    // 验证码位数 也就是 循环的次数 是 number 次 也就是 循环 1-number次
    for(var i = 1 ; i <= number ; i++){
        // 生成随机索引下标
        var index = parseInt( Math.random()*str.length ) ;

        // 如果 bool 是 true 就直接拼接 随机生成的 验证码字符
        if(bool){
            // 通过索引下标,直接获取字符,拼接入vc验证码字符串
            vc += str[index];
        }else{
        // 如果 bool 是 false 不允许 有重复字符
            // 执行判断如果 随机字符串 不在 vc验证码中 再拼接 
            if( vc.indexOf( str[index] ) === -1 ){
                vc += str[index];
            }else{
                // 随机字符,已经在vc验证码中,再次循环一次
                i--;
            }
        }
    }

    // 将生成的字符串,作为返回值
    return vc;
}






/*
    随机数函数

    返回值 是 随机颜色 
        方法1 返回值是 css3 支持的 颜色的英文单词
        方法2 返回值是 #和6位十六进制数值
        方法3 返回值是 rgb() 形式

*/ 

function setColor(){
    // 方法1: 定义数组,存储所有支持的颜色英文单词
    // 随机生成索引下标 从数组中 获取一个英文单词
    // var colorArr = ['black','silver','gray','white','maroon','red','purple','fuchsia','green','lime','olive','yellow','navy','blue','teal','aqua','orange','aliceblue','antiquewhite','aquamarine','azure','beige','bisque','blanchedalmond','blueviolet','brown','burlywood','cadetblue','chartreuse','chocolate','coral','cornflowerblue','cornsilk','crimson','darkblue','darkcyan','darkgoldenrod','darkgray','darkgreen','darkgrey','darkkhaki','darkmagenta','darkolivegreen','darkorange','darkorchid','darkred','darksalmon','darkseagreen','darkslateblue','darkslategray','darkslategrey','darkturquoise','darkviolet','deeppink','deepskyblue','dimgray','dimgrey','dodgerblue','firebrick','floralwhite','forestgreen','gainsboro','ghostwhite','gold','goldenrod','greenyellow','grey','honeydew','hotpink','indianred','indigo','ivory','khaki','lavender','lavenderblush','lawngreen','lemonchiffon','lightblue','lightcoral','lightcyan','lightgoldenrodyellow','lightgray','lightgreen','lightgrey','lightpink','lightsalmon','lightseagreen','lightskyblue','lightslategray','lightslategrey','lightsteelblue','lightyellow','limegreen','linen','mediumaquamarine','mediumblue','mediumorchid','mediumpurple','mediumseagreen','mediumslateblue','mediumspringgreen','mediumturquoise','mediumvioletred','midnightblue','mintcream','mistyrose','moccasin','navajowhite','oldlace','olivedrab','orangered','orchid','palegoldenrod','palegreen','paleturquoise','palevioletred','papayawhip','peachpuff','peru','pink','plum','powderblue','rosybrown','royalblue','saddlebrown','salmon','sandybrown','seagreen','seashell','sienna','skyblue','slateblue','slategray','slategrey','snow','springgreen','steelblue','tan','thistle','tomato','turquoise','violet','wheat','whitesmoke','yellowgreen','rebeccapurple'];
    // 随机生成 索引下标 从数组中获取 颜色单词 设定为返回值
    // 随机数的范围 0 - 最后一个单元的索引下标 
    // 也就是 0 -  colorArr.length-1
    // return colorArr[parseInt( Math.random()*colorArr.length )];

    // 方法2: #和6位十六进制数值
    // 定义一个字符串,内容是 0-9和a-f 十六进制的所有字符
    // 现在需要6位可以重复的 随机的 十六进制字符 
    // 通过循环 循环6次 每次生成一个 随机的索引下标 从字符串中获取 十六进制字符

    // 十六进制字符
    // var str = '0123456789abcdef';
    // // 定义空字符串,存储颜色字符,默认内容为#
    // var color = '#';
    // // 循环6次,每次生成一个随机索引下标,从字符串中获取随机字符,拼接入color字符串
    // for(var i = 1 ; i <= 6 ; i++){
    //     // 每次循环,生成一个随机的索引下标
    //     var index = parseInt( Math.random()*str.length );
    //     // 通过随机索引下标获取 随机字符,拼接入 color 字符串
    //     color += str[index];
    // }
    // return color;

    // 方法3 rgb()
    // rgb() 每一个属性值 是 0-255 的数值
    // 通过 随机数 设定 三个 随机数值
    return `rgb(${parseInt(Math.random()*256 )},${parseInt( Math.random()*256 )},${parseInt( Math.random()*256 )})`;
}






// 获取时间对象储存的具体时间信息
function getTimeObj(time){
    // 使用兼容语法,创建时间对象
    // 如果没有输入实参,按照当前时间 创建时间对象
    // 如果有输入的实参,按照实参时间 创建时间对象
    var t = time === undefined ? new Date() : new Date(time);

    // 获取对应的时间数据

    // 年
    var year = t.getFullYear();

    // 月
    var month = t.getMonth()+1;
    // 前导补零
    month = month < 10 ? '0'+month : month;

    // 日
    var day = t.getDate();
    // 前导补零
    day = day < 10 ? '0'+day : day;


    // 星期
    var weekArr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
    var week = weekArr[ t.getDay() ];

    // 时
    var hour = t.getHours();
    // 前导补零
    hour = hour < 10 ? '0'+hour : hour;

    // 分
    var minute = t.getMinutes();
    // 前导补零
    minute = minute < 10 ? '0'+minute : minute;

    // 秒
    var second = t.getSeconds();
    // 前导补零
    second = second < 10 ? '0'+second : second;

    // 使用对象的特殊语法,创建对象
    return {year,month,day,week,hour,minute,second};
}






// 获取时间差函数
// 参数1 : 设定的终止时间
// 返回值 : 当前时间距离终止时间的天,小时,分钟,秒
//         返回值的形式是 对象
function getCountDown(endTime){
    // 创建时间对象
    // 起始时间对象就是当前时间
    var st = new Date();
    // 结束事件对象是参数输入的时间
    var et = new Date(endTime);

    // 获取时间差 转化为秒数
    // 两个时间戳相减 结果除以1000 取整
    var time = parseInt( ( et.getTime() - st.getTime() ) / 1000 );

    // 转化为对应的天,小时,分钟,秒
    var d = parseInt( time / (24*60*60) );
    var h = parseInt( time % (24*60*60) / (60*60) );
    var m = parseInt( time % (60*60) / 60 );
    var s = time % 60 ;

    // 前导补零
    d = d < 10 ? '0'+d : d;
    h = h < 10 ? '0'+h : h;
    m = m < 10 ? '0'+m : m;
    s = s < 10 ? '0'+s : s;

    return {d,h,m,s};
}






// 获取 地址栏 url中的参数数据
// 转化为 对应的 对象
function getUrlVal(){
    // 1, 创建对象,存储键值对数据
    var obj = {};
    // 2, 获取地址栏参数字符串,去掉第一个字符?问号
    // 从索引是1 也就是 第二个字符 开始截取
    var str = window.location.search.substr(1);
    // 3, 将字符串 以 & 符号为间隔 分割为数组
    // 单元存储的就是 每一个独立的 键值对字符串
    var arr1 = str.split('&');
    // 4, 循环遍历 arr1数组 将存储的 键值对字符串 以 =等号 为间隔分为个数组
    arr1.forEach(function(item){
        var arr2 = item.split('=');
        obj[arr2[0]] = window.decodeURIComponent( arr2[1] ); 
    })
    // 5, 返回值 是 设定的对象
    return obj;
}






// // 运动函数

// function move(element , styleObj , endFun = function(){}){
//     // 定义一个变量 存储 定时器个数
//     // 初始值 是 0 也就是 定时器默认 是 0个
//     let t = 0;

//     for( let type in styleObj ){
//         // 每循环一次 一定会 有一个属性 对应一个定时器
//         // 变量储存数值 累加1
//         t++;

//         // 如果 type 属性 是 opacity 透明度 就 将最终数值 乘以100 其他属性不变
//         let endVal = type === 'opacity' ? styleObj[type]*100 : styleObj[type];

//         // 如果 type 属性 是 opacity 透明度 就 获取结果直接*100 其他属性 parseInt() 获取整数部分
//         let startVal =  type === 'opacity' ? myGetStyle( element , type )*100 : parseInt( myGetStyle( element , type ) );

//         let time = setInterval(function () {
//             // 计算步长  (最终值 - 初始值) / 次数
//             let sped = (endVal - startVal) / 5;
//             // 步长取整  步长>0 向上取整  否则 向下取整
//             sped = sped > 0 ? Math.ceil(sped) : Math.floor(sped);
//             // 初始值是累加步长
//             startVal += sped;

//             // 累加之后的初始值赋值给 标签对象
//             // 如果 type 属性 是 opacity 透明度 就 除以100赋值 其他属性 拼接px单位赋值
//             element.style[type] = type === 'opacity' ? startVal/100 : startVal + 'px';

//             // 判断清除定时器
//             if (startVal === endVal) {
//                 // 清除定时器
//                 clearInterval(time);
//                 // 清除定时器 变量 执行 累减操作
//                 t--;

//                 // 如果 t 为 0 证明所有的定时器 清除完毕
//                 // 证明运动真正的停止了
//                 if(t === 0){
//                     // 运动停止了,调用 对应的 参数3 输入的函数程序
//                     endFun();
//                     //全局---window,undefind
//                 }
//             }
//         }, 30)                
//     }
// }


/**
 * 绑定事件的函数
 * @param {node} ele 要绑定事件的元素
 * @param {string} type 要绑定的事件类型
 * @param {function} fn 要处理事件的函数
 */
//  function bindEvent(ele,type,fn){
//     if(ele.addEventListener){
//         ele.addEventListener(type,fn)
//     }else{
//         ele.attachEvent('on'+type,fn)
//     }
// }
function bindEvent(ele,type,handler){
    if(ele.addEventListener){
        ele.addEventListener(type,handler)
    }else if(ele.attachEvent){
        ele.attachEvent('on'+type,handler)
    }else{
        ele['on'+type] = handler
    }
}



/**
 * 解绑事件的函数
 * @param {node} ele 要绑定事件的元素
 * @param {string} type 要绑定的事件类型
 * @param {function} fn 要处理事件的函数
 */
// function unBind(ele,type,fn){
//     if(ele.removeEventListener){
//         ele.removeEventListener(type,fn)
//     }else{
//         ele.detachEvent('on'+type,fn)
//     }
// }
function unBind(ele,type,handler){
    if(ele.removeEventListener){
        ele.removeEventListener(type,handler)
    }else if(ele.detachEvent){
        ele.detachEvent('on'+type,handler)
    }else{
        ele['on'+type] = null
    }
}


/**
 * 获取一个范围内的随机整数
 * @param {number} a 表示范围的数字
 * @param {number} b 表示范围的数字
 */
 function getRandom(a,b){
    var max = a;
    var min = b;
    if(a<b){
        max = b
        min = a
    }
    return parseInt(Math.random() * (max+1-min)) + min
}





/**
 * 兼容的获取样式的函数
 * @param {node} ele 获取样式的那个标签对象
 * @param {string} attr 获取样式中的css属性名
 */
 function getStyle(ele,attr){
    if(window.getComputedStyle){
        return window.getComputedStyle(ele)[attr]
    }else{
        return ele.currentStyle[attr]
    }
}



/**
 * 设置样式的函数
 * @param {node} ele 要设置样式的那个标签对象
 * @param {object} styleObj 要设置的样式，css的属性和值组成的对象
 */
 function setStyle(ele,styleObj){
    for(var attr in styleObj){
        ele.style[attr] = styleObj[attr]
    }
}






/**
 * 运动函数
 * @param {node} attr  要运动的元素需要改变的属性
 * @param {object} obj 要运动的属性的变化值
 * @param {node} ele  要运动的标签对象
 */
function move1(attr,target,ele){
    var timerId = setInterval(function(){
        // 让left、top、width ... 通用
        var style = getStyle(ele,attr) // 获取到的属性是 XXpx
        // 取整
        style = parseInt(style)
        // 增加
        style += 2
        // 做判断
        if(style >= target){
            style = target
            // 清除定时器
            clearInterval(timerId)
        }
        // 设置样式
        ele.style[attr] = style  +"px";
        // ele.style.attr = style  +"px";
        console.log(111);
    },20)
}






/**
 * 动画函数
 * @param {node} ele 要运动的元素
 * @param {object} obj 要运动的属性组成的对象
 */
 function move2(ele,obj,fn){
    var k = 0
    var n = 0
    // 遍历对象，在循环中创建定时器
    for(let attr in obj){
        k++
        // 在循环中执行异步代码，所以要将循环的var换成let
        let timerId = setInterval(function(){
            var target = obj[attr]
            
            // 让left、top、width ... 通用
            var style = getStyle(ele,attr) // 获取到的属性是 XXpx
            if(attr === 'opacity'){
                style *= 100
                target *= 100
            }
            // 取整
            style = parseInt(style)
            // 增加
            // 计算运动的速度
            // 求出距离目的地还有多远
            var diff = target - style;
            // 不论远近，都按照一定的比例去运动
            // 求比例
            var speed = diff/20
            // 这样走，距离目的地越来越近，但是走的也越来越小，永远到不了目的地
            // speed = Math.ceil(speed)
            if(speed>0){
                speed = Math.ceil(speed)
            }else{
                speed = Math.floor(speed)
            }
            style += speed
            // 做判断
            if(style === target){
                style = target
                if(attr === 'opacity'){
                    ele.style[attr] = style/100
                }else{
                    ele.style[attr] = style  +"px"
                }
                // 清除定时器
                clearInterval(timerId)
                n++
                // 当n和k相等的时候就表示所有运动都结束了
                if(k === n){
                    // console.log("所有运动都结束了");
                    // 运动结束之后我们要执行的代码不确定
                    // 调用函数就好
                    fn()
                }
            }else{
                if(attr === 'opacity'){
                    ele.style[attr] = style/100
                }else{
                    ele.style[attr] = style  +"px"
                }
            }
        },20)
    }
}





// 分页插件
/**
 * 分页插件
 * @param {node} classname
 * @param {object} obj 对象
 */
// 定义构造函数
function Page(classname,obj={}){
    this.obj = obj
    this.show = obj.show || function(){}
    this.default = {
        pageData:{
            total:100,
            pageSize:12,
        },
        symbol:{
            first:"首页",
            prev:"上一页", 
            list:'',
            next:"下一页", 
            last:"末页" 
        }
    }
    this.setDefault()
    this.totalPage = Math.ceil(this.default.pageData.total / this.default.pageData.pageSize)
    this.currentPage = 1
    this.list = null
    this.box = document.querySelector('.'+classname)
    this.container = document.createElement('div')
    this.setStyle(this.container,{
        width:"100%",
        height:"50px",
        display:"flex",
        justifyContent:"center",
        "align-items":"center"
    })
    this.container.onmouseover = ()=>{
        this.container.style.cursor = "pointer"
    }
    this.container.onselectstart = ()=>{
        return false;
    }
    this.box.appendChild(this.container)
    this.createTag()
    this.init()
    this.skip()
    this.tabPage()
}
Page.prototype.init = function(){
    this.createPage()
    this.setDisabled()
    this.container.children[5].value = this.currentPage
    this.show(this.currentPage)
}
Page.prototype.skip = function(){
    var input = document.createElement('input')
    input.setAttribute('type','number')
    this.container.appendChild(input)
    this.setStyle(input,{
        outline: 'none',
        padding: '6px',
        border: '1px solid #ccc',
        width: '46px',
        height: '19px',
        margin:"0 5px"
    })
    var btn = document.createElement('button')
    btn.innerText = 'GO';
    this.container.appendChild(btn)
    this.setStyle(btn,{
        width: '46px',
        height: '33px',
        outline: 'none',
        border: '1px solid #ccc',
        margin: '0 5px',
        "background-color": 'skyblue',
    })
    btn.onmouseover = ()=>{
        btn.style.cursor = "pointer"
    }
}
Page.prototype.setDisabled = function(){
    if(this.currentPage === 1){
        this.container.children[0].style.backgroundColor = '#eee';
        this.container.children[1].style.backgroundColor = '#eee';
        this.container.children[0].setAttribute('disabled','true')
        this.container.children[1].setAttribute('disabled','true')
    }else{
        this.container.children[0].style.backgroundColor = 'transparent';
        this.container.children[1].style.backgroundColor = 'transparent';
        this.container.children[0].removeAttribute('disabled')
        this.container.children[1].removeAttribute('disabled')
    }
    if(this.currentPage === this.totalPage){
        this.container.children[3].style.backgroundColor = '#eee';
        this.container.children[4].style.backgroundColor = '#eee';
        this.container.children[3].setAttribute('disabled','true')
        this.container.children[4].setAttribute('disabled','true')
    }else{
        this.container.children[3].style.backgroundColor = 'transparent';
        this.container.children[4].style.backgroundColor = 'transparent';
        this.container.children[3].removeAttribute('disabled')
        this.container.children[4].removeAttribute('disabled')
    }
}
Page.prototype.tabPage = function(){
    this.container.onclick = e=>{
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.className === 'first' && target.getAttribute('disabled')!=='true'){
            this.currentPage = 1
            this.init()
        }else if(target.className === 'prev' && target.getAttribute('disabled')!=='true'){
            this.currentPage--
            this.init()
        }else if(target.className === 'next' && target.getAttribute('disabled')!=='true'){
            this.currentPage++
            this.init()
        }else if(target.className === 'last' && target.getAttribute('disabled')!=='true'){
            this.currentPage = this.totalPage
            this.init()
        }else if(target.tagName === "P" && target.innerText-0 !== this.currentPage){
            this.currentPage = target.innerText-0
            this.init()
        }else if(target.tagName === 'BUTTON' && this.currentPage!==target.previousElementSibling.value-0){
            if(target.previousElementSibling.value-0>=this.totalPage){
                target.previousElementSibling.value = this.totalPage
            }
            if(target.previousElementSibling.value-0<=1){
                target.previousElementSibling.value = 1
            }
            this.init()
        }
    }
}
Page.prototype.createP = function(start,end){
    for(var i=start;i<=end;i++){
        var p = document.createElement('p')
        p.innerText = i;
        this.setStyle(p,{
            margin:"5px",
            padding:"5px",
            border:"1px solid #ccc"
        })
        if(i === this.currentPage){
            p.style.backgroundColor = 'orange';
        }
        this.list.appendChild(p)
    }
}
Page.prototype.createPage = function(){
    this.list.innerHTML = '';
    if(this.totalPage<=5){
        this.createP(1,this.totalPage)
    }else{
        if(this.currentPage<=3){
            this.createP(1,5)
        }
        else if(this.currentPage>=this.totalPage-2){
            this.createP(this.totalPage-4,this.totalPage)
        }
        else{
            this.createP(this.currentPage-2,this.currentPage+2)
        }
    }
}
Page.prototype.setStyle = function(ele,styleObj){
    for(var attr in styleObj){
        ele.style[attr] = styleObj[attr]
    }
}
Page.prototype.createTag = function(){
    for(var attr in this.default.symbol){
        var div = document.createElement('div')
        div.innerText = this.default.symbol[attr]
        if(attr !== 'list'){
            this.setStyle(div,{
                margin:"5px",
                padding:"5px",
                border:"1px solid #ccc"
            })
        }else{
            this.list = div
            this.setStyle(div,{
                display:"flex",
                justifyContent:"center",
                alignItems:"center"
            })
        }
        div.className = attr
        this.container.appendChild(div)
    }
}
Page.prototype.setDefault = function(){
    for(var attr in this.obj.pageData){
        this.default.pageData[attr] = this.obj.pageData[attr]
    }
    for(var attr in this.obj.symbol){
        this.default.symbol[attr] = this.obj.symbol[attr]
    }
}
/**************************** 分页插件的使用模板 *****************************/
// 参数1：要放分页的大盒子的类名
// 参数2：插件的配置
// pageData代表分页数据 - 需要total键和pageSize键，分别代表总共多少条数据，每页显示多少条
// new Page('pagination',{
//     pageData:{
//         total:arr.length,
//         pageSize
//     },
//     // symbol表示显示的符号
//     symbol:{
//         first:'',
//         prev:'',
//         next:'',
//         last:''
//     },
//     // 使用插件，需要有真实的数据，截取数据使用
//     show:function(currentPage){
//         var brr = arr.slice((currentPage-1)*pageSize,currentPage*pageSize)
//         var str = '';
//         for(var i=0;i<brr.length;i++){
//             str += `
//                 <tr>
//                     <td>${brr[i].id}</td>
//                     <td>${brr[i].name}</td>
//                     <td>${brr[i].sex}</td>
//                     <td>${brr[i].age}</td>
//                 </tr>
//             `
//         }
//         document.querySelector('tbody').innerHTML = str
//     }
// })






/**
 * 设置cookie的函数
 * @param {string} key 设置的cookie的键
 * @param {string} value cookie的值
 * @param {number} seconds 秒数
 * @param {string} path 路径
 */
 function setCookie(key,value,seconds,path='/'){
	var date = new Date()
	date.setTime(date.getTime()-8*3600*1000+seconds*1000)
	document.cookie = `${key}=${value};expires=${date};path=${path}`
}


/**
 * 获取cookie的函数
 * @param {string} key 要获取的cookie的键
 */
function getCookie(key){
	var cookies = document.cookie;
	var arr = cookies.split('; ')
	for(var i=0;i<arr.length;i++){
		var brr = arr[i].split('=')
		if(brr[0] === key){
			return brr[1]
		}		
	}	
}


/**
 * 删除cookie的函数
 * @param {string} key cookie的键
 * @param {string} path 路径
 */
function removeCookie(key,path='/'){
	setCookie(key,null,-1,path)
}






/**
 * Ajax
 * @param {object} obj 传入的数据 - 对象形式
 */
// get请求和post、请求如果在不传数据的情况下一样的
function sendAjax(obj){
    // 请求地址
    if(obj.url === undefined){
        throw new Error("请求地址必填")
    }
    if(Object.prototype.toString.call(obj.url) !== '[object String]'){
        throw new Error("请求地址不合法")
    }
    // 请求方式 - 将请求方式作为一个默认值，如果不传，默认get
    if(obj.method === undefined){
        obj.method = 'get'
    }
    if(obj.method !== 'get' && obj.method !== 'post'){
        throw new Error("请求方式不合法")
    }
    // 判断async参数是否传送
    if(obj.async === undefined){
        obj.async = true
    }
    // 如果传了async就需要判断一下async的类型
    if(Object.prototype.toString.call(obj.async) !== '[object Boolean]'){
        // alert("async参数不对，必须是布尔值")
        // return false;
        // 抛出自定义错误
        throw new Error("async参数不对，必须是布尔值")
    }
    // 如果数据传了 - 判断是字符串还是对象
    if(obj.data !== undefined){
        // 判断是否是字符串
        if(Object.prototype.toString.call(obj.data) === '[object String]'){
            // 如果传进来的是字符串数据，将字符串数据赋值给变量str
            var str = obj.data
        }else if(Object.prototype.toString.call(obj.data) === '[object Object]'){
            // 如果传进来的数据是对象，将对象转成字符串数据
            var str = '';
            var f = ''
            for(var attr in obj.data){
                str += f + attr + '=' + obj.data[attr]
                f = '&'
            }
        }else{
            throw new Error("数据必须是字符串或对象")
        }
        // 分支语句执行完我们会得到一个str字符串数据 - 拼接的地址后面
        if(obj.method === 'get'){
            obj.url = obj.url + '?' + str
        }
    }
    // 判断dataType参数
    if(obj.dataType !== undefined){
        if(obj.dataType !== 'xml' && obj.dataType !== 'json'){
            throw new Error("dataType必须是xml或json")
        }
    }
    // 判断success和error的类型
    if(obj.success === undefined){
        obj.success = function(){}
    }
    if(Object.prototype.toString.call(obj.success) !== '[object Function]'){
        throw new Error("success必须是函数")
    }

    if(obj.error === undefined){
        obj.error = function(){}
    }
    if(Object.prototype.toString.call(obj.error) !== '[object Function]'){
        throw new Error("error必须是函数")
    }
    var xhr = new XMLHttpRequest()
    var res;
    xhr.onreadystatechange = function(){
        if(xhr.readyState === 4){
            if(xhr.status<300 && xhr.status>=200){
                // 通过传进来的dataType参数，来判断需要哪种接收方式
                if(obj.dataType === 'xml'){
                    var res = xhr.responseXML;
                }else if(obj.dataType === 'json'){
                    // 如果是json字符串，就应该转换成对象或数组
                    var res = xhr.responseText;
                    res = JSON.parse(res)
                }else{
                    var res = xhr.responseText;
                }
                
                // console.log(res);
                obj.success(res)
                // 返回值 - 因为这里是事件函数中，所以不能给大函数返回
                // return res
            }else{
                // 如果请求错误了
                obj.error()
            }
        }
    }
    xhr.open(obj.method,obj.url,obj.async)
    if(obj.data && obj.method === 'post'){
        xhr.setRequestHeader("content-type",'application/x-www-form-urlencoded')
        xhr.send(str)
        return false;
    }
    xhr.send()
    // 因为ajax是异步请求，所以不能返回了
    // return res;
}
////////////////////// ajax调用的模板 //////////////////////////
/*
sendAjax({
    method:"get", // 请求方式 - 可选项，默认是get
    url:"demo.php", // 请求地址 - 必填项
    async:true, // 是否发送异步请求 - 可选项，默认是true
    data:"name=zhangsan&age=12", // 请求主体 - 可选项（没有默认值） - 可以是字符串，可以是对象
    dataType:'xml/json', // 最终想要响应回来的数据的类型 - 可选项 - 如果响应的xml文件的内容，就用xml，如果响应的数据是json对象，就用json，其他普通字符串，就省略
    success:function(a){ // 响应成功以后要处理的响应的主体 - a是形参我们自定义的，随便起名字 - a就是接收到的响应主体
        console.log(a);
    },
    error:function(){ // 响应失败以后要处理的失败逻辑 - 可选项
        console.log("请求失败了");
    }
})
*/





/**
 * promise函数
 * @param {object} obj 传入的数据 - 对象形式
 */
function promiseAjax(obj){
    return new Promise(function(resolve,reject){
        if(obj.url === undefined){
            throw new Error("请求地址必填")
        }
        if(Object.prototype.toString.call(obj.url) !== '[object String]'){
            throw new Error("请求地址不合法")
        }
        if(obj.method === undefined){
            obj.method = 'get'
        }
        if(obj.method !== 'get' && obj.method !== 'post'){
            throw new Error("请求方式不合法")
        }
        if(obj.async === undefined){
            obj.async = true
        }
        if(Object.prototype.toString.call(obj.async) !== '[object Boolean]'){
            throw new Error("async参数不对，必须是布尔值")
        }
        if(obj.data !== undefined){
            if(Object.prototype.toString.call(obj.data) === '[object String]'){
                var str = obj.data
            }else if(Object.prototype.toString.call(obj.data) === '[object Object]'){
                var str = '';
                var f = ''
                for(var attr in obj.data){
                    str += f + attr + '=' + obj.data[attr]
                    f = '&'
                }
            }else{
                throw new Error("数据必须是字符串或对象")
            }
            if(obj.method === 'get'){
                obj.url = obj.url + '?' + str
            }
        }
        if(obj.dataType !== undefined){
            if(obj.dataType !== 'xml' && obj.dataType !== 'json'){
                throw new Error("dataType必须是xml")
            }
        }
        var xhr = new XMLHttpRequest()
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4){
                if(xhr.status<300 && xhr.status>=200){
                    if(obj.dataType === 'xml'){
                        var res = xhr.responseXML;
                    }else if(obj.dataType === 'json'){
                        var res = xhr.responseText;
                        res = JSON.parse(res)
                    }else{
                        var res = xhr.responseText;
                    }
                    resolve(res)
                }else{
                    reject()
                }
            }
        }
        xhr.open(obj.method,obj.url,obj.async)
        if(obj.data && obj.method === 'post'){
            xhr.setRequestHeader("content-type",'application/x-www-form-urlencoded')
            xhr.send(str)
            return false;
        }
        xhr.send()
    })
}

/*************************************** promiseAjax使用示例 **************************************/
// promiseAjax({
//     method:"get", // 请求方式 - 可选项，默认是get
//     url:"demo.php", // 请求地址 - 必填项
//     async:true, // 是否发送异步请求 - 可选项，默认是true
//     data:"name=zhangsan&age=12", // 请求主体 - 可选项（没有默认值） - 可以是字符串，可以是对象
//     dataType:'xml/json', // 最终想要响应回来的数据的类型 - 可选项 - 如果响应的xml文件的内容，就用xml，如果响应的数据是json对象，就用json，其他普通字符串，就省略
// }).then(function(res){
    // console.log(res) // res是最终请求回来的响应主体
// })
